<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <p>{{count}}</p>
        <p><button @click="count++">count++</button></p>
        <hr>
        <p>{{obj.a}}----{{obj.b}}</p>
        <p>
            <button @click="addA">a++</button>
            <button @click="addB">b++</button>
            <button @click="reset">reset</button>
        </p>
    </div>
</body>
<script>

    // 组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量，并将从多个函数中得到的状态组合起来处理复杂问题

    let {createApp,getCurrentInstance} = Vue;
    let {ref} = Vue;
    let {shallowRef,triggerRef} = Vue;
    let {onMounted} = Vue;


    let app = createApp({
        setup(props) {

            // ref()  => 创建一个对"值类型"数据的引用,返回一个ref对象 (存对象类型也可以)
            // 注意:
            // 1. setup函数中对ref对象取值和赋值 依赖于.value属性
            // 2. 代理对象中 / template中 ref对象会被解包 => 直接使用变量即可
            // 3. ref() 也可以存对象类型, 此时Vue响应式对ref数据的数据拦截是深层的(可以检测value值是否改变,也可以检测子对象上属性是否改变 => 触发视图更新)

            // let count = ref(10);  // {value:10}
            // console.log(count);

            // let obj = ref({a:1,b:2});   // {value:{a:1,b:2}}
            // console.log(obj);


            // shallowRef()   =>  ref() 的浅层作用形式。=>只关注ref对象的value值是否发生改变, 不管value对应的值是 值类型还是引用类型
            // shallowRef() 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。

            // triggerRef()​
            // 强制触发依赖于一个浅层 ref 的副作用，这通常在对浅引用的内部值进行深度变更后使用。



            // 获取当前Vue实例
            let app = getCurrentInstance();
            console.log("当前Vue实例",app);

            // app => 当前组件
            // app.appContext => 当前组件对应根组件
            console.log("根组件的全局属性",app.appContext.config.globalProperties);


            console.log("当前Vue实例的代理对象",app.ctx);
            console.log("当前Vue实例的props",app.props);
            console.log("当前Vue实例的attrs",app.attrs);
            console.log("当前Vue实例的slots",app.slots);
            console.log("当前Vue实例的refs",app.refs);
            console.log("当前Vue实例的parent",app.parent);
            console.log("当前Vue实例的emit",app.emit);

            let {$a,$b} = app.appContext.config.globalProperties;  // 获取全局属性
            let ctx = app.ctx;  // 获取当前Vue实例的代理对象



            let count = shallowRef(10);  // {value:10}
            console.log(count);

            let obj = shallowRef({a:1,b:2});   // {value:{a:1,b:2}}
            console.log(obj);

            let addA = ()=>{
                obj.value.a++
                console.log(obj.value.a);
                // triggerRef(obj);

                ctx.$forceUpdate();
            }
            let addB = ()=>{
                obj.value.b++
                console.log(obj.value.b);

                // triggerRef(obj);
                ctx.$forceUpdate();
            }
            let reset = ()=>{
                obj.value = {a:10,b:20};
            }


            // onMounted  注册一个回调函数，在组件挂载完成后执行。
            onMounted(()=>{
                console.log("mounted",$a,$b);
            })
         
            

            return {
                count:count,
                obj:obj,
                addA:addA,
                addB:addB,
                reset:reset,
            }
        },
        mounted() {
            console.log("代理对象,this",this);
        },
    })
    console.log("app",app);

    app.config.globalProperties.$a =1;
    app.config.globalProperties.$b =2;

    app.mount("#app");


</script>

</html>